﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Util
{
    public class ConnectionsCache<T> : IDisposable where T : class
    {
        private readonly Dictionary<string, SoapConnection<T>> connections = new Dictionary<string, SoapConnection<T>>();

        [MethodImpl(MethodImplOptions.Synchronized)]
        public SoapConnection<T> GetConnection(string uri, TimeSpan? timeout = null)
        {
            SoapConnection<T> connection;
            if (!connections.TryGetValue(uri, out connection))
            {
                connection = new SoapConnection<T>(uri, timeout);
                connections[uri] = connection;
            }

            var channel = (IChannel) connection.Channel;
            if (channel.State != CommunicationState.Opened)
            {
                connection.Dispose();
                connection = new SoapConnection<T>(uri, timeout);
                connections[uri] = connection;
            }

            return connection;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public void RemoveConnection(string uri)
        {
            SoapConnection<T> connection;
            if (connections.TryGetValue(uri, out connection))
            {
                connections.Remove(uri);
                connection.Dispose();
            }
        }

        public void Dispose()
        {
            foreach (var connection in connections.Values)
            {
                connection.Dispose();
            }
        }
    }
}
